package com.silverhaze.web.util;

import com.silverhaze.web.data.DatabaseEntity;
import com.silverhaze.web.data.wot.WoTDayStatistics;
import com.silverhaze.web.data.wot.WoTDayTankStatistics;
import com.silverhaze.web.data.wot.WoTPlayer;
import com.silverhaze.web.data.wot.WoTTank;
import com.silverhaze.web.data.wot.presentation.WoTPlayerDayStatistics;
import com.silverhaze.web.data.wot.presentation.WoTPlayerStatistics;
import com.silverhaze.web.data.wot.presentation.WoTTankStatistics;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.*;
import java.sql.Date;
import java.util.*;

/**
 * User: Babanin
 * Date: 07.01.12
 * Time: 22:30
 */
public final class EntityManageUtil {
    public static Connection createConnection() throws SQLException, NamingException {
        Context initCtx = new InitialContext();
        Context envCtx = (Context) initCtx.lookup("java:comp/env");
        DataSource ds = (DataSource) envCtx.lookup("jdbc/silverweb");

        return ds.getConnection();
    }

    public static WoTPlayer persist(WoTPlayer player) {
        try {
            Connection connection = createConnection();
            PreparedStatement statement = connection.prepareStatement("INSERT INTO wot_player(user, wotProfileUrl, registrationDate, lastUpdateTime) VALUES (?, ?, ?, ?)");

            statement.setString(1, player.getUser());
            statement.setString(2, player.getWotProfileUrl());
            statement.setDate(3, player.getRegistrationDate() != null ? new Date(player.getRegistrationDate().getTime()) : null);
            statement.setDate(4, player.getLastUpdateTime() != null ? new Date(player.getLastUpdateTime().getTime()) : null);

            statement.executeUpdate();

            player.setId(getLastId(statement));

            statement.close();
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }

        return player;
    }

    public static void update(WoTPlayer player) {
        try {
            Connection connection = createConnection();
            PreparedStatement statement = connection.prepareStatement("UPDATE wot_player SET user = ?, wotProfileUrl = ?, registrationDate = ?, lastUpdateTime = ? WHERE id = ?");

            statement.setString(1, player.getUser());
            statement.setString(2, player.getWotProfileUrl());
            statement.setDate(3, new Date(player.getRegistrationDate().getTime()));
            statement.setDate(4, new Date(player.getLastUpdateTime().getTime()));
            statement.setLong(5, player.getId());

            statement.executeUpdate();

            player.setId(getLastId(statement));

            statement.close();
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    public static <T extends DatabaseEntity> List<T> load(Class<T> clazz) {
        if (WoTPlayer.class.equals(clazz)) {
            List<T> result = new ArrayList<T>();

            try {
                Connection connection = createConnection();
                Statement statement = connection.createStatement();

                ResultSet resultSet = statement.executeQuery("SELECT * FROM wot_player");
                result = (List<T>) parsePlayers(resultSet);

                statement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (NamingException e) {
                e.printStackTrace();
            }

            return result;
        } else if (WoTTank.class.equals(clazz)) {
            List<T> result = new ArrayList<T>();

            try {
                Connection connection = createConnection();
                Statement statement = connection.createStatement();

                ResultSet resultSet = statement.executeQuery("SELECT * FROM wot_tank");
                result = (List<T>) parseTanks(resultSet);

                statement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (NamingException e) {
                e.printStackTrace();
            }

            return result;
        }

        if (clazz != null) {
            throw new IllegalStateException("Unknown entity class " + clazz.getName());
        } else {
            throw new IllegalStateException("Entity class is null");
        }
    }

    public static <T extends DatabaseEntity> T load(Class<T> clazz, long id) {
        if (WoTPlayer.class.equals(clazz)) {
            WoTPlayer player = null;

            try {
                Connection connection = createConnection();
                Statement statement = connection.createStatement();

                ResultSet resultSet = statement.executeQuery("SELECT * FROM wot_player WHERE id = " + id);
                List<WoTPlayer> woTPlayers = parsePlayers(resultSet);

                if (!woTPlayers.isEmpty()) {
                    player = woTPlayers.get(0);
                }

                statement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (NamingException e) {
                e.printStackTrace();
            }

            return (T) player;
        }

        if (clazz != null) {
            throw new IllegalStateException("Unknown entity class " + clazz.getName());
        } else {
            throw new IllegalStateException("Entity class is null");
        }
    }

    private static List<WoTPlayer> parsePlayers(ResultSet resultSet) {
        List<WoTPlayer> result = new ArrayList<WoTPlayer>();

        try {
            while (resultSet.next()) {
                WoTPlayer player = new WoTPlayer();

                player.setId(resultSet.getLong("id"));
                player.setUser(resultSet.getString("user"));
                player.setWotProfileUrl(resultSet.getString("wotProfileUrl"));
                player.setLastUpdateTime(resultSet.getDate("lastUpdateTime"));
                player.setRegistrationDate(resultSet.getDate("registrationDate"));

                result.add(player);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return result;
    }

    private static List<WoTTank> parseTanks(ResultSet resultSet) {
        List<WoTTank> result = new ArrayList<WoTTank>();

        try {
            while (resultSet.next()) {
                WoTTank player = new WoTTank();

                player.setId(resultSet.getLong("id"));
                player.setTankName(resultSet.getString("tankName"));
                player.setTankImageUrl(resultSet.getString("tankImageUrl"));

                result.add(player);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return result;
    }

    private static long getLastId(Statement statement) throws SQLException {
        ResultSet keys = statement.getGeneratedKeys();
        keys.next();

        long id = keys.getInt(1);
        keys.close();

        return id;
    }

    public static WoTTank persist(WoTTank tank) {
        try {
            Connection connection = createConnection();
            PreparedStatement statement = connection.prepareStatement("INSERT INTO wot_tank(tankName, tankImageUrl) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS);

            statement.setString(1, tank.getTankName());
            statement.setString(2, tank.getTankImageUrl());

            statement.executeUpdate();

            tank.setId(getLastId(statement));

            statement.close();
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }

        return tank;
    }

    public static WoTDayStatistics persist(WoTDayStatistics dayStatistics) {
        try {
            Connection connection = createConnection();
            PreparedStatement statement = connection.prepareStatement("INSERT INTO wot_day_statistics(accuracy, averageExp, baseAttackPoints, baseDefencePoints, " +
                    "battles, damagePoints, `DATE`, discovered, killed, looses, maxBattleExp, survive, totalExp, wins, dayStatistics_player) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);

            statement.setInt(1, dayStatistics.getAccuracy());
            statement.setInt(2, dayStatistics.getAverageExp());
            statement.setInt(3, dayStatistics.getBaseAttackPoints());
            statement.setInt(4, dayStatistics.getBaseDefencePoints());
            statement.setInt(5, dayStatistics.getBattles());
            statement.setInt(6, dayStatistics.getDamagePoints());
            statement.setDate(7, new Date(dayStatistics.getDate().getTime()));
            statement.setInt(8, dayStatistics.getDiscovered());
            statement.setInt(9, dayStatistics.getKilled());
            statement.setInt(10, dayStatistics.getLooses());
            statement.setInt(11, dayStatistics.getMaxBattleExp());
            statement.setInt(12, dayStatistics.getSurvive());
            statement.setInt(13, dayStatistics.getTotalExp());
            statement.setInt(14, dayStatistics.getWins());
            statement.setLong(15, dayStatistics.getPlayer().getId());

            statement.executeUpdate();

            dayStatistics.setId(getLastId(statement));

            statement.close();
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }

        return dayStatistics;
    }

    public static WoTDayTankStatistics persist(WoTDayTankStatistics dayTankStats) {
        try {
            Connection connection = createConnection();
            PreparedStatement statement = connection.prepareStatement("INSERT INTO wot_day_tank_statistics(battles, win, dayTankStatistics_dayStatistics, dayTankStatistics_tank) VALUES (?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);

            statement.setInt(1, dayTankStats.getBattles());
            statement.setInt(2, dayTankStats.getWin());
            statement.setLong(3, dayTankStats.getDayStatistics().getId());
            statement.setLong(4, dayTankStats.getTank().getId());

            statement.executeUpdate();

            dayTankStats.setId(getLastId(statement));

            statement.close();

            statement = connection.prepareStatement("UPDATE wot_tank SET tankImageUrl = ? WHERE id = ?");

            statement.setString(1, dayTankStats.getTank().getTankImageUrl());
            statement.setLong(2, dayTankStats.getTank().getId());

            statement.executeUpdate();

            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }

        return dayTankStats;
    }

    public static void removeDayStatistics(Date date) {
        try {
            Connection connection = createConnection();

            PreparedStatement selectDayStatisticsStatement = connection.prepareStatement("SELECT s.id FROM wot_day_statistics AS s WHERE s.date = ?");
            selectDayStatisticsStatement.setDate(1, date);

            ResultSet resultSet = selectDayStatisticsStatement.executeQuery();
            while (resultSet.next()) {
                long wotStatisticsId = resultSet.getLong(1);

                PreparedStatement deleteDayTankStatisticsStatement = connection.prepareStatement("DELETE FROM wot_day_tank_statistics WHERE dayTankStatistics_dayStatistics = ?");
                deleteDayTankStatisticsStatement.setLong(1, wotStatisticsId);
                deleteDayTankStatisticsStatement.executeUpdate();
                deleteDayTankStatisticsStatement.close();

                PreparedStatement deleteDayStatisticsStatement = connection.prepareStatement("DELETE FROM wot_day_statistics WHERE id = ?");
                deleteDayStatisticsStatement.setLong(1, wotStatisticsId);
                deleteDayStatisticsStatement.executeUpdate();
                deleteDayStatisticsStatement.close();
            }

            resultSet.close();
            selectDayStatisticsStatement.close();

            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    public static List<WoTTankStatistics> loadTankStatistics(Date from, Date till) {
        List<WoTTankStatistics> result = new ArrayList<WoTTankStatistics>();

        class TempTankStorage {
            public String tank;
            public String tankImage;
            public String player;

            public int win;
            public int battles;

            public java.util.Date date;
        }

        Map<String, Map<String, List<TempTankStorage>>> tankMapStorage = new HashMap<String, Map<String, List<TempTankStorage>>>();

        try {
            Connection connection = createConnection();
            PreparedStatement selectTankStats = connection.prepareStatement("SELECT wt.tankName, wdts.battles, wdts.win, wp.user, wds.date, wt.tankImageUrl FROM wot_day_statistics AS wds \n" +
                    " JOIN wot_day_tank_statistics AS wdts ON wdts.dayTankStatistics_dayStatistics = wds.id \n" +
                    " JOIN wot_tank AS wt ON wt.id = wdts.dayTankStatistics_tank \n" +
                    " JOIN wot_player AS wp ON wds.dayStatistics_player = wp.id\n" +
                    " WHERE wds.date BETWEEN ? AND ? ORDER BY wt.`tankName`");

            selectTankStats.setDate(1, from);
            selectTankStats.setDate(2, till);

            ResultSet resultSet = selectTankStats.executeQuery();
            while (resultSet.next()) {
                TempTankStorage tempTankStorage = new TempTankStorage();
                tempTankStorage.tank = resultSet.getString(1);
                tempTankStorage.battles = resultSet.getInt(2);
                tempTankStorage.win = resultSet.getInt(3);
                tempTankStorage.player = resultSet.getString(4);
                tempTankStorage.date = resultSet.getDate(5);
                tempTankStorage.tankImage = resultSet.getString(6);

                Map<String, List<TempTankStorage>> playerTankStorage = tankMapStorage.get(tempTankStorage.tank);
                if (playerTankStorage == null) {
                    playerTankStorage = new HashMap<String, List<TempTankStorage>>();
                    tankMapStorage.put(tempTankStorage.tank, playerTankStorage);
                }

                List<TempTankStorage> tankStorage = playerTankStorage.get(tempTankStorage.player);
                if (tankStorage == null) {
                    tankStorage = new ArrayList<TempTankStorage>();
                    playerTankStorage.put(tempTankStorage.player, tankStorage);
                }

                tankStorage.add(tempTankStorage);
            }

            resultSet.close();
            selectTankStats.close();
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }

        for (Map.Entry<String, Map<String, List<TempTankStorage>>> entry : tankMapStorage.entrySet()) {
            String tank = entry.getKey();
            Map<String, List<TempTankStorage>> tanksByPlayer = entry.getValue();

            int wins = 0;
            int battles = 0;
            String tankImageUrl = null;
            for (Map.Entry<String, List<TempTankStorage>> playerTanks : tanksByPlayer.entrySet()) {
                List<TempTankStorage> tanks = playerTanks.getValue();

                if (tanks.size() >= 2) {
                    Collections.sort(tanks, new Comparator<TempTankStorage>() {
                        public int compare(TempTankStorage o1, TempTankStorage o2) {
                            return o1.date.compareTo(o2.date);
                        }
                    });

                    TempTankStorage first = tanks.get(0);
                    TempTankStorage last = tanks.get(tanks.size() - 1);

                    wins += (last.win - first.win);
                    battles += (last.battles - first.battles);
                    tankImageUrl = first.tankImage;
                }
            }

            if (battles > 0 && wins >= 0) {
                WoTTankStatistics tankStatistics = new WoTTankStatistics();
                tankStatistics.setBattles(battles);
                tankStatistics.setWins(wins);
                tankStatistics.setTank(tank);
                tankStatistics.setTankImage(tankImageUrl);

                result.add(tankStatistics);
            }
        }

        Collections.sort(result, new Comparator<WoTTankStatistics>() {
            public int compare(WoTTankStatistics o1, WoTTankStatistics o2) {
                return o2.getBattles() - o1.getBattles();
            }
        });

        return result;
    }

    public static List<WoTPlayerStatistics> loadPlayersStatistics(Date from, Date till) {
        List<WoTPlayerStatistics> result = new ArrayList<WoTPlayerStatistics>();
        Map<String, List<WoTDayStatistics>> playerStat = new HashMap<String, List<WoTDayStatistics>>();

        try {
            Connection connection = createConnection();

            PreparedStatement selectPlayerStats = connection.prepareStatement("SELECT wp.user, wds.date, wds.battles, wds.wins, wds.looses, wds.killed, " +
                    "wds.discovered, wds.damagePoints, wds.baseAttackPoints, wds.baseDefencePoints, " +
                    "wds.totalExp FROM wot_day_statistics AS wds JOIN wot_player AS wp ON " +
                    "wds.dayStatistics_player = wp.id WHERE wds.date BETWEEN ? AND ? ORDER BY wp.user");

            selectPlayerStats.setDate(1, from);
            selectPlayerStats.setDate(2, till);

            ResultSet selectPlayerStatsResultSet = selectPlayerStats.executeQuery();

            while (selectPlayerStatsResultSet.next()) {
                String playerName = selectPlayerStatsResultSet.getString(1);

                WoTDayStatistics dayStatistics = new WoTDayStatistics();
                dayStatistics.setDate(selectPlayerStatsResultSet.getDate(2));
                dayStatistics.setBattles(selectPlayerStatsResultSet.getInt(3));
                dayStatistics.setWins(selectPlayerStatsResultSet.getInt(4));
                dayStatistics.setLooses(selectPlayerStatsResultSet.getInt(5));
                dayStatistics.setKilled(selectPlayerStatsResultSet.getInt(6));
                dayStatistics.setDiscovered(selectPlayerStatsResultSet.getInt(7));
                dayStatistics.setDamagePoints(selectPlayerStatsResultSet.getInt(8));
                dayStatistics.setBaseAttackPoints(selectPlayerStatsResultSet.getInt(9));
                dayStatistics.setBaseDefencePoints(selectPlayerStatsResultSet.getInt(10));
                dayStatistics.setTotalExp(selectPlayerStatsResultSet.getInt(11));

                List<WoTDayStatistics> dayStats = playerStat.get(playerName);
                if (dayStats == null) {
                    dayStats = new ArrayList<WoTDayStatistics>();
                    playerStat.put(playerName, dayStats);
                }

                dayStats.add(dayStatistics);
            }

            selectPlayerStatsResultSet.close();
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }

        for (Map.Entry<String, List<WoTDayStatistics>> entry : playerStat.entrySet()) {
            String playerName = entry.getKey();
            List<WoTDayStatistics> dayStats = entry.getValue();

            if (dayStats.size() < 2) {
                continue;
            }

            Collections.sort(dayStats, new Comparator<WoTDayStatistics>() {
                public int compare(WoTDayStatistics o1, WoTDayStatistics o2) {
                    return o1.getDate().compareTo(o2.getDate());
                }
            });

            WoTDayStatistics first = dayStats.get(0);
            WoTDayStatistics last = dayStats.get(dayStats.size() - 1);

            int battleCount = last.getBattles() - first.getBattles();

            if (battleCount > 0) {
                WoTPlayerStatistics playerStatistics = new WoTPlayerStatistics();
                playerStatistics.setPlayer(playerName);
                playerStatistics.setBattles(battleCount);
                playerStatistics.setWins(last.getWins() - first.getWins());
                playerStatistics.setLooses(last.getLooses() - first.getLooses());
                playerStatistics.setKilled(last.getKilled() - first.getKilled());
                playerStatistics.setDamagePoints(last.getDamagePoints() - first.getDamagePoints());
                playerStatistics.setDiscovered(last.getDiscovered() - first.getDiscovered());
                playerStatistics.setBaseAttackPoints(last.getBaseAttackPoints() - first.getBaseAttackPoints());
                playerStatistics.setBaseDefencePoints(last.getBaseDefencePoints() - first.getBaseDefencePoints());
                playerStatistics.setTotalExp(last.getTotalExp() - first.getTotalExp());

                result.add(playerStatistics);
            }
        }

        Collections.sort(result, new Comparator<WoTPlayerStatistics>() {
            public int compare(WoTPlayerStatistics o1, WoTPlayerStatistics o2) {
                return o2.getBattles() - o1.getBattles();
            }
        });

        return result;
    }

    public static List<WoTPlayerDayStatistics> loadPlayerStatistics(WoTPlayer player, Date from) {
        List<WoTPlayerDayStatistics> result = new ArrayList<WoTPlayerDayStatistics>();

        try {
            Connection connection = createConnection();

            PreparedStatement selectPlayerStats = connection.prepareStatement("SELECT wds.* FROM wot_day_statistics AS wds " +
                    "JOIN wot_player AS wp ON wds.`dayStatistics_player` = wp.`id` WHERE wds.`date` >= ? AND wp.`id` = ?");

            selectPlayerStats.setDate(1, from);
            selectPlayerStats.setLong(2, player.getId());

            ResultSet selectPlayerStatsResultSet = selectPlayerStats.executeQuery();
            List<WoTDayStatistics> dayStatistics = new ArrayList<WoTDayStatistics>();
            while (selectPlayerStatsResultSet.next()) {
                WoTDayStatistics dayStats = new WoTDayStatistics();
                dayStats.setId(selectPlayerStatsResultSet.getLong("id"));
                dayStats.setDate(selectPlayerStatsResultSet.getDate("date"));
                dayStats.setBattles(selectPlayerStatsResultSet.getInt("battles"));
                dayStats.setWins(selectPlayerStatsResultSet.getInt("wins"));
                dayStats.setLooses(selectPlayerStatsResultSet.getInt("looses"));
                dayStats.setKilled(selectPlayerStatsResultSet.getInt("killed"));
                dayStats.setDiscovered(selectPlayerStatsResultSet.getInt("discovered"));
                dayStats.setDamagePoints(selectPlayerStatsResultSet.getInt("damagePoints"));
                dayStats.setBaseAttackPoints(selectPlayerStatsResultSet.getInt("baseAttackPoints"));
                dayStats.setBaseDefencePoints(selectPlayerStatsResultSet.getInt("baseDefencePoints"));
                dayStats.setTotalExp(selectPlayerStatsResultSet.getInt("totalExp"));

                PreparedStatement selectPlayerTankStats = connection.prepareStatement("SELECT wt.tankName, wt.tankImageUrl, wdts.* FROM wot_day_tank_statistics AS wdts JOIN wot_tank AS wt ON wt.id = wdts.dayTankStatistics_tank WHERE wdts.`dayTankStatistics_dayStatistics` = ?");
                selectPlayerTankStats.setLong(1, dayStats.getId());

                ResultSet selectPlayerTankStatsResultSet = selectPlayerTankStats.executeQuery();
                List<WoTDayTankStatistics> dayTankStatistics = new ArrayList<WoTDayTankStatistics>();
                while (selectPlayerTankStatsResultSet.next()) {
                    WoTDayTankStatistics dayTankStats = new WoTDayTankStatistics();

                    WoTTank tank = new WoTTank();
                    tank.setTankName(selectPlayerTankStatsResultSet.getString(1));
                    tank.setTankImageUrl(selectPlayerTankStatsResultSet.getString(2));

                    dayTankStats.setTank(tank);
                    dayTankStats.setId(selectPlayerTankStatsResultSet.getLong(3));
                    dayTankStats.setBattles(selectPlayerTankStatsResultSet.getInt(4));
                    dayTankStats.setWin(selectPlayerTankStatsResultSet.getInt(5));

                    dayTankStatistics.add(dayTankStats);
                }

                selectPlayerTankStatsResultSet.close();

                dayStats.setDayTankStatistics(dayTankStatistics);
                dayStatistics.add(dayStats);
            }

            selectPlayerStatsResultSet.close();
            connection.close();

            if (dayStatistics.size() > 1) {
                Collections.sort(dayStatistics, new Comparator<WoTDayStatistics>() {
                    @Override
                    public int compare(WoTDayStatistics o1, WoTDayStatistics o2) {
                        return o1.getDate().compareTo(o2.getDate());
                    }
                });

                for (int i = 1; i < dayStatistics.size(); i++) {
                    WoTDayStatistics current = dayStatistics.get(i);
                    WoTDayStatistics previous = dayStatistics.get(i - 1);

                    if (current.getDate().getTime() - previous.getDate().getTime() <= DateUtil.MSECS_IN_DAY) {
                        WoTPlayerStatistics playerStatistics = new WoTPlayerStatistics();

                        playerStatistics.setBattles(current.getBattles() - previous.getBattles());
                        playerStatistics.setBaseAttackPoints(current.getBaseAttackPoints() - previous.getBaseAttackPoints());
                        playerStatistics.setBaseDefencePoints(current.getBaseDefencePoints() - previous.getBaseDefencePoints());
                        playerStatistics.setDamagePoints(current.getDamagePoints() - previous.getDamagePoints());
                        playerStatistics.setDiscovered(current.getDiscovered() - previous.getDiscovered());
                        playerStatistics.setKilled(current.getKilled() - previous.getKilled());
                        playerStatistics.setLooses(current.getLooses() - previous.getLooses());
                        playerStatistics.setWins(current.getWins() - previous.getWins());
                        playerStatistics.setTotalExp(current.getTotalExp() - previous.getTotalExp());

                        List<WoTTankStatistics> tankStatistics = new ArrayList<WoTTankStatistics>();
                        for (WoTDayTankStatistics currentTankStatistics : current.getDayTankStatistics()) {
                            for (WoTDayTankStatistics previousTankStatistics : previous.getDayTankStatistics()) {
                                if (currentTankStatistics.getTank().equals(previousTankStatistics.getTank())) {
                                    int battles = currentTankStatistics.getBattles() - previousTankStatistics.getBattles();
                                    int wins = currentTankStatistics.getWin() - previousTankStatistics.getWin();

                                    if (battles > 0 && wins >= 0) {
                                        WoTTankStatistics tankStat = new WoTTankStatistics();

                                        tankStat.setTank(currentTankStatistics.getTank().getTankName());
                                        tankStat.setTankImage(currentTankStatistics.getTank().getTankImageUrl());
                                        tankStat.setBattles(battles);
                                        tankStat.setWins(wins);

                                        tankStatistics.add(tankStat);
                                    }
                                }
                            }
                        }

                        Collections.sort(tankStatistics, new Comparator<WoTTankStatistics>() {
                            @Override
                            public int compare(WoTTankStatistics o1, WoTTankStatistics o2) {
                                return o2.getBattles() - o1.getBattles();
                            }
                        });

                        result.add(new WoTPlayerDayStatistics(current.getDate(), playerStatistics, tankStatistics));
                    }
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }

        Collections.sort(result, new Comparator<WoTPlayerDayStatistics>() {
            public int compare(WoTPlayerDayStatistics o1, WoTPlayerDayStatistics o2) {
                return o2.getDate().compareTo(o1.getDate());
            }
        });

        return result;
    }
}